(function(Backbone, _){
	var __Application = Class.extend({
	    appName: null,
        dbIns: null,
        dbNames: null,
        dbStores: null,
        router: null,
        beforeStartFunction: null,
        colls: null,
        sectionsContainer: null,
        renderedViews: null,
        lists: null,
        init: function(){
            this.appName = null;
            this.lists = {};
            this.renderedViews = {};
            this.colls = {};
            this.router = null;
            this.dbIns = null,
            this.dbNames = new Array();
            this.dbStores = {};
            this.beforeStartFunction = null;
            this.sectionsContainer = null;
            this.setAppName();
        },
        setAppName: function(appName){
            this.appName = util_fwk_base.isDefined(appName) ? appName: 'generic-app-' + new Date().getTime().toString();
        },
        ignite: function(){
            if(this.dbIns == null){
                this.setDbIns('tester', '', 'tester description', (1024 * 1024));
            }
            var dbNames = _.clone(this.dbNames);
            var that = this;
            this._initStores(dbNames, function(){
                var dbNames = _.clone(that.dbNames);
                that.setCollections();
                that._fetchStoresData(dbNames, that.beforeStartApp);
            });
        },
        setCollections: function(){
            for(var i=0;i<this.dbNames.length;i++){
                var dbName = this.dbNames[i];
                this.colls[dbName] = new window['coll_' + dbName]();
                this.colls[dbName].store = this.getDbStore(dbName);
            }
        },
        _fetchStoresData: function(dbNames, callBack){
            if(dbNames.length == 0){
                callBack.call(this);
            }else{
                var dbName = dbNames.shift();
                var that = this;
                this.colls[dbName].fetch({
                    success: function(res){
                        return that._fetchStoresData(dbNames,  callBack);
                    }
                });
            }
        },
        setRouter: function(router){
            this.router = router
        },
        _initStores: function(dbNames, callBack){
            if(dbNames.length == 0){
                callBack.call(this);
            }else{
                var that = this;
                var dbName = dbNames.shift();
                return this.setDbStore(dbName, function(){
                    return that._initStores(dbNames, callBack);
                });
            }
        },
        setDbIns: function(name, version, description, size){
            this.dbIns = window.openDatabase(name, version, description, size);
        },
        setDbNames: function(dbNames){
            this.dbNames = dbNames;
        },
        getDbNames: function(){
            return this.dbNames;
        },
        getDbStore: function(dbName){
            return this.dbStores[dbName];
        },
        setDbStore: function(dbName, callBack){
            this.dbStores[dbName] = new Backbone.WebSQLStore(this.dbIns, dbName, callBack, callBack);
        },
        setBeforeStartFunction: function(starterCallback){
            this.beforeStartFunction = starterCallback;
        },
        beforeStartApp: function(){
            var that = this;
            if(typeof this.beforeStartFunction != 'undefined' && this.beforeStartFunction != null){
                this.beforeStartFunction.call(this, this, function(){
                    that.startApp();
                });
                
            }else{
                this.startApp();
            }
        },
        startApp: function(){
            this.router = new this.router();
            Backbone.history.start({pushState: false});
            if(window.location.hash == '')
            this.router.navigate(this.router.defaultRoute, {trigger: true, replace: false});
        },
        setSectionsContainer: function(selector){
            this.sectionsContainer = selector;
        },
        makeSectionId: function(pageId){
            return this.appName + '-' + pageId;
        },
        getSection: function(pageId){
            var sectionId = this.makeSectionId(pageId);
            var $section = $('#'+ sectionId);
            if($section.length == 0){
                $section = $('<section></section>').attr('id', sectionId); 
                $(this.sectionsContainer).append($section);
            }
            return $section;
        },
        changePage: function(pageId){
            var sectionId = this.makeSectionId(pageId);
            //$(this.sectionsContainer + ' section').not('#' + sectionId).hide();
            //hide everyhting first
            $(this.sectionsContainer + ' section').hide();
            //show the section only
            var $section = $('#'+ sectionId).show();
            this.setRenderedView(pageId);
            $('html, body').animate({ scrollTop: 0 }, 'fast');
        },
        setRenderedView: function(pageId){
            if(typeof this.renderedViews[pageId] == 'undefined' || this.renderedViews[pageId] == null){
                this.renderedViews[pageId] = this.makeSectionId(pageId);
                return true;
            }
            return false;
        },
        getRenderedView: function(pageId){
            //rendered already
            if(typeof this.renderedViews[pageId] != 'undefined' && this.renderedViews[pageId] != null) return this.renderedViews[pageId];
            return null;
        },
        unsetRenderedView: function(pageId){
            if(typeof this.renderedViews[pageId] != 'undefined' && this.renderedViews[pageId] != null){
                this.renderedViews[pageId] = null;
                delete this.renderedViews[pageId];
                return true;
            }
            return false;
        },
        makeListItem: function(key, label, desc){
            return {
                "label": label,
                "desc": desc,
                "key": key
            };
        },
        getList: function(listId){
            var list = {};
            if(listId.endsWith('_db')){
                var collName = listId.replace('_db', '');
                if(typeof __app.colls[collName] != 'undefined'){
                    var collection = __app.colls[collName];
                    var that = this;
                    collection.each(function(model){
                        var modelId = model.get('id');
                        var label = modelId;
                        if(typeof model.get('name') != 'undefined'){
                            label = model.get('name');
                        }
                        list[model.get('id')] = that.makeListItem(modelId, label, modelId);
                    });
                }
            }else{
                if(typeof this.lists[listId] != 'undefined')
                    list = this.lists[listId];
            }
            return list;
        },
        setLists: function(listsObj){
            for(var listId in listsObj){
                if(listsObj.hasOwnProperty(listId)){
                    this.setList(listId, listsObj[listId]);
                }
            }
        },
        setList: function(listId, list){
            this.lists[listId] = list;
        },
        
        makePageId: function(section, action, ident){
            var pageId = util_fwk_base.isDefined(section)? section: 'genericpage';
            pageId += util_fwk_base.isDefined(action) ?('-' + action): '';
            pageId += util_fwk_base.isDefined(ident)?('-' + ident): '';
            return pageId;
        }
    });
    
    __app = new __Application();
})(Backbone, _);



